# import matplotlib.pylab as plt
import numpy as np


# from pylab import *


# 神经网络的一个重要性质是它可以自动地从数据中学习到合适的权重参数。

# def step_function(x):
#     y = x > 0
#     return y.astype(np.int)

def step_funcion(x):
    return np.array(x > 0, dtype=int)


# x = np.arange(-5.0,5.0,0.1)
# y = step_funcion(x)
# plt.plot(x,y)
# plt.ylim(-0.1,1.1)
# plt.show()

def sigmoid(x):
    return 1 / (1 + np.exp(-x))


# x = np.arange(-5.0,5.0,0.1)
# y = sigmoid(x)
# plt.plot(x,y)
# plt.ylim(-0.1,1.1)
# plt.show()

# ReLU函数
def relu(x):
    return np.maximum(0, x)


# 恒等函数：将输入原样输出
def identity_function(x):
    return x


# softmax函数
# softmax函数的输出是0.0到1.0之间的实数。并且，softmax
# 函数的输出值的总和是1。输出总和为1是softmax函数的一个重要性质。正
# 因为有了这个性质，我们才可以把softmax函数的输出解释为“概率”
# 这里需要注意的是，即便使用了softmax函数，各个元素之间的大小关
# 系也不会改变。这是因为指数函数（y = exp(x)）是单调递增函数。实际上，
# 上例中a的各元素的大小关系和y的各元素的大小关系并没有改变。
def softmax(a):
    c = np.max(a)
    exp_a = np.exp(a - c)
    sum_exp_a = np.sum(exp_a)
    y = exp_a / sum_exp_a
    return y


# 多维数组的运算
# A = np.array([1,2,3,4])
# print(A)
# np.ndim(A) #获得数组的维数
# A.shape # 获得数组的形状，结果为元组
# A.shape[0]

# B = np.array([[1,2],[3,4],[5,6]])
# print(B)
# X = np.array([1,2])
# W = np.array([[1,3,5],[2,4,6]])
# Y = np.dot(X,W)
# print(Y)

# 神经网络的内积

# # 第1层的加权和 A = X*W + B
# X = np.array([1.0,0.5])
# W1 = np.array([[0.1,0.3,0.5],[0.2,0.4,0.6]])
# B1 = np.array([0.1,0.2,0.3])
#
# # print(W1.shape)
# # print(X.shape)
# # print(B1.shape)
# A1 = np.dot(X, W1) + B1
# # print(A1)
# Z1 = sigmoid(A1)
# print(Z1)
#
# # 第2层
# W2 = np.array([[0.1, 0.4], [0.2, 0.5], [0.3, 0.6]])
# B2 = np.array([0.1, 0.2])
# # print(Z1.shape) # (3,)
# # print(W2.shape) # (3, 2)
# # print(B2.shape) # (2,)
# A2 = np.dot(Z1, W2) + B2
# Z2 = sigmoid(A2)
# print(Z2)
#
# # 输出层
# W3 = np.array([[0.1, 0.3], [0.2, 0.4]])
# B3 = np.array([0.1, 0.2])
# A3 = np.dot(Z2, W3) + B3
# Y = identity_function(A3) # 或者Y = A3 输出层的激活函数用恒等函数 一般地，回
# # 归问题可以使用恒等函数，二元分类问题可以使用 sigmoid函数，多元分类问题可以使用 softmax函数。
# print(Y)


# 按照神经网络的实现惯例，只把权重记为大
# 写字母W1，其他的（偏置或中间结果等）都用小写字母表示。
def init_network():
    network = {}
    network['W1'] = np.array([[0.1, 0.3, 0.5], [0.2, 0.4, 0.6]])
    network['b1'] = np.array([0.1, 0.2, 0.3])
    network['W2'] = np.array([[0.1, 0.4], [0.2, 0.5], [0.3, 0.6]])
    network['b2'] = np.array([0.1, 0.2])
    network['W3'] = np.array([[0.1, 0.3], [0.2, 0.4]])
    network['b3'] = np.array([0.1, 0.2])
    return network


def forward(network, x):
    W1, W2, W3 = network['W1'], network['W2'], network['W3']

    b1, b2, b3 = network['b1'], network['b2'], network['b3']

    a1 = np.dot(x, W1) + b1
    z1 = sigmoid(a1)

    a2 = np.dot(z1, W2) + b2
    z2 = sigmoid(a2)

    a3 = np.dot(z2, W3) + b3
    y = identity_function(a3)
    return y

# network = init_network()
# x = np.array([1.0,0.5])
# y = forward(network,x)
# print(y)


# x = np.array([1.5,2.6,-3.0])
# y = softmax(x)
# print(y)

